package com.atguigu.lease.web.admin.service.impl;

import ch.qos.logback.classic.pattern.RootCauseFirstThrowableProxyConverter;
import com.atguigu.lease.common.constant.RedisConstant;
import com.atguigu.lease.common.exception.LeaseException;
import com.atguigu.lease.common.result.ResultCodeEnum;
import com.atguigu.lease.common.utils.JwtUtil;
import com.atguigu.lease.model.entity.SystemUser;
import com.atguigu.lease.model.enums.BaseStatus;
import com.atguigu.lease.web.admin.mapper.SystemUserMapper;

import com.atguigu.lease.web.admin.service.LoginService;
import com.atguigu.lease.web.admin.service.SystemUserService;
import com.atguigu.lease.web.admin.vo.login.CaptchaVo;
import com.atguigu.lease.web.admin.vo.login.LoginVo;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wf.captcha.SpecCaptcha;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;


import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class LoginServiceImpl implements LoginService {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private SystemUserMapper systemUserMapper;

    @Override
    public CaptchaVo getCaptcha() {
        //1.在pom中导入easyCaptcha依赖,通过specCaptcha创建验证码对象.
        SpecCaptcha specCaptcha = new SpecCaptcha(138, 40, 2);
        //2.把验证码对象转为文本,再转为小写字母,前端传过来的也要转为小写字母,做好统一.
        String code = specCaptcha.text().toLowerCase();
        //3.admin:login: + uuid作为key
        String key = RedisConstant.ADMIN_LOGIN_PREFIX + UUID.randomUUID().toString().replaceAll("-","");
        //4.把key和code放入redis
        redisTemplate.opsForValue().set(key,code,RedisConstant.ADMIN_LOGIN_CAPTCHA_TTL_SEC, TimeUnit.SECONDS);
        //5.把CaptchaVo返回给前端,第一个参数是把图片转成base64编码,可以在web页面显示,第二个key是用来检验前端输入完传递过来的code的
        return new CaptchaVo(specCaptcha.toBase64(),key);
    }

        @Override
        public String login(LoginVo loginVo) {
            //1.判定前端code是否为null
            if (loginVo.getCaptchaCode()==null){
                throw new LeaseException(ResultCodeEnum.ADMIN_CAPTCHA_CODE_NOT_FOUND);
            }
            //2.判定redis里的code是否为null,为空代表已过期
            String code = (String) redisTemplate.opsForValue().get(loginVo.getCaptchaKey());
            if (code==null){
                throw new LeaseException(ResultCodeEnum.ADMIN_CAPTCHA_CODE_EXPIRED);
            }
            //3.判定redis里的code是否等于前端传过来的code
            if (!code.equals(loginVo.getCaptchaCode())){
                throw new LeaseException(ResultCodeEnum.ADMIN_CAPTCHA_CODE_ERROR);
            }

            //4.调数据库查用户,如果前面写了select=false,就不能利用service或者mapper层自带的方法来获取对象,因为password查不到,为空,要自定义一个方法;
            LambdaQueryWrapper<SystemUser> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SystemUser::getUsername,loginVo.getUsername());
            SystemUser systemUser = systemUserMapper.selectOne(wrapper);
//        SystemUser systemUser = systemUserMapper.selectByUsername(loginVo.getUsername());

            //5.判定systemUser是否为空
            if (systemUser==null){
                throw new LeaseException(ResultCodeEnum.ADMIN_ACCOUNT_NOT_EXIST_ERROR);
            }

            //6.判定systemUser状态是否被禁用
            if (systemUser.getStatus().getCode()==0){
                throw new LeaseException(ResultCodeEnum.ADMIN_ACCOUNT_DISABLED_ERROR);
            }

            //7.判定密码是否正确
            if (!systemUser.getPassword().equals(DigestUtils.md5Hex(loginVo.getPassword()))){
                throw new LeaseException(ResultCodeEnum.ADMIN_ACCOUNT_ERROR);
            }

            return JwtUtil.createToken(systemUser.getId());
        }
    }



